package outPut

import (
	"fmt"
	"db2s/global"
	"os"
	"reflect"
	"strings"
)

type Print string

const (
	CSymbol  = "/*@*/"
	RSymbol  = "/*$*/"
	FileName = "FileName"
)

var FName Print = FileName

type Result interface {
	CreateFile() (bool, error)
	AppendWrite(sheetName string, writeS any) bool
	Read() any
	Read1() any
	Close() error
}
type FileOperations interface {
	Init() (err error)
	Open(fileName string) (any, error)
	Close() error
	Read() (any, error)
	Write(sheetName string, writeS any) error
	Head() (err error)
	Create() error
	Print(s Print) (r any)
	//Delete(sheetName string) bool
	//Rename(oldName, newName string) bool
}
type StreamRes interface {
	Start()
	AddFunc(f global.EFunc)
	Stop()
	Write(s any)
	Run()
	Load(pods string, value any) (err error)
	Print()
}

func mapToStruct(m map[string]any, s any) any {
	rt := reflect.TypeOf(s)
	rv := reflect.ValueOf(s)

	if rt.Kind() == reflect.Ptr {
		rt = rt.Elem()
		rv = rv.Elem()
	}
	for i := 0; i < rt.NumField(); i++ {
		field := rt.Field(i)
		value, ok := m[field.Tag.Get("json")]
		if ok {
			fieldValue := rv.Field(i)
			fieldValue.Set(reflect.ValueOf(value))
		}
	}
	return rv.Interface()
}
func NewStreamRes(s any) (ff StreamRes) {
	switch s.(type) {
	case Cell:
		q := s.(Cell)
		ff = &q
	case Terminal:
		q := s.(Terminal)
		ff = &q
	}
	return
}
func NewFileOperations(s any) (ff FileOperations) {
	switch s.(type) {
	case Xls:
		q := s.(Xls)
		ff = &q
	case Tex:
		q := s.(Tex)
		ff = &q
	}
	return
}
func FileOut(outType string, fileInfo map[string]any) (ff Result) {
	switch strings.ToLower(outType) {
	case "xls":
		ff = &exl{
			xlsFileName:        fmt.Sprintf("%s.xlsx", fileInfo["fileName"].(string)),
			xlsSafetySwitch:    fileInfo["safety"].(bool),
			xlsSheetNameGather: fileInfo["sheetGather"].([]string),
			xlsTailGather:      fileInfo["tailGather"].(map[string]string),
		}
	case "text":
		t := &Text{CurryThreads: 20}
		mapToStruct(fileInfo, t)
		if v1, ok := fileInfo["fileN"]; ok {
			if v1 != nil {
				t.FileN = fileInfo["fileN"].(*os.File)
			}
		}
		return t
	}
	return
}
